<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BoLe HR 智能招聘系统 - LangGraph多智能体版本</title>
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/marked@9.1.2/lib/marked.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
    <script>
        // 确保marked正确加载 - 立即检查并设置备用方案
        (function() {
            // 立即创建备用marked函数，避免undefined错误
            if (typeof window.marked === 'undefined') {
                console.warn('⚠️ marked.js 未立即可用，使用备用实现');
                window.marked = {
                    parse: function(text) {
                        if (!text) return '';
                        return text
                            .replace(/\*\*(.*?)\*\*/g, '<strong class="font-bold">$1</strong>') // **粗体**
                            .replace(/\*(.*?)\*/g, '<em class="italic">$1</em>') // *斜体*
                            .replace(/`(.*?)`/g, '<code class="bg-gray-100 px-1 py-0.5 rounded text-xs font-mono">$1</code>') // `代码`
                            .replace(/### (.*?)(?=\n|$)/g, '<h3 class="text-base font-bold mt-3 mb-2 text-gray-800">$1</h3>') // ### 三级标题
                            .replace(/## (.*?)(?=\n|$)/g, '<h2 class="text-lg font-bold mt-3 mb-2 text-gray-800">$1</h2>') // ## 二级标题
                            .replace(/# (.*?)(?=\n|$)/g, '<h1 class="text-xl font-bold mt-3 mb-2 text-gray-800">$1</h1>') // # 一级标题
                            .replace(/^\* (.*)$/gm, '<li class="ml-4 mb-1">• $1</li>') // * 列表项
                            .replace(/^\d+\. (.*)$/gm, '<li class="ml-4 mb-1 list-decimal">$1</li>') // 1. 有序列表
                            .replace(/^\- (.*)$/gm, '<li class="ml-4 mb-1">- $1</li>') // - 列表项
                            .replace(/\n\n/g, '</p><p class="mb-2">') // 双换行成段落
                            .replace(/\n/g, '<br/>') // 单换行
                            .replace(/^/, '<p class="mb-2">') // 开始段落
                            .replace(/$/, '</p>'); // 结束段落
                    },
                    setOptions: function() {
                        // 空实现，兼容marked的setOptions调用
                    }
                };
            }
            
            // 等待DOM和外部脚本加载完成后重新检查
            window.addEventListener('DOMContentLoaded', function() {
                setTimeout(function() {
                    if (typeof window.marked !== 'undefined' && window.marked.version) {
                        console.log('✅ marked.js 外部版本加载成功:', window.marked.version);
                        // 如果外部marked已加载，设置默认选项
                        try {
                            window.marked.setOptions({
                                breaks: true,     // 支持换行
                                gfm: true,        // GitHub风格markdown 
                                sanitize: false   // 允许HTML (谨慎使用)
                            });
                        } catch (e) {
                            console.warn('设置marked选项失败:', e);
                        }
                    } else {
                        console.log('📝 使用备用markdown解析器');
                    }
                }, 100);
            });
        })();
    </script>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
        }
        .gradient-bg {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
        }
        .chat-container {
            height: 450px;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            z-index: 10;
            position: relative;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
        }
        .chat-messages {
            height: 320px;
            overflow-y: auto;
            max-height: 320px;
        }
        .message-user {
            background: #007bff;
            color: white;
            margin-left: auto;
            max-width: 70%;
        }
        .message-assistant {
            background: #f1f3f4;
            color: #333;
            margin-right: auto;
            max-width: 80%;
        }
        .candidate-detail-panel {
            height: calc(100vh - 650px);
            overflow-y: auto;
            min-height: 400px;
        }
        .candidate-list-panel {
            height: calc(100vh - 650px);
            overflow-y: auto;
            min-height: 400px;
        }
        .workspace-content {
            margin-top: 0;
            position: relative;
            z-index: 1;
        }
        .score-excellent { background: linear-gradient(135deg, #4ade80, #22c55e); }
        .score-good { background: linear-gradient(135deg, #22d3ee, #0ea5e9); }
        .score-average { background: linear-gradient(135deg, #fbbf24, #f59e0b); }
        .score-poor { background: linear-gradient(135deg, #f87171, #ef4444); }
        .typing-indicator {
            display: inline-block;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background-color: #ccc;
            animation: pulse 1.5s ease-in-out infinite;
        }
        @keyframes pulse {
            0% { transform: scale(0); opacity: 1; }
            100% { transform: scale(1); opacity: 0; }
        }
        .markdown-content h1, .markdown-content h2, .markdown-content h3 {
            font-weight: bold;
            margin: 16px 0 8px 0;
        }
        .markdown-content ul, .markdown-content ol {
            margin: 8px 0;
            padding-left: 20px;
        }
        .markdown-content p {
            margin: 8px 0;
        }
        .status-active { border-left: 4px solid #22c55e; }
        .status-archived { border-left: 4px solid #6b7280; opacity: 0.7; }
        .status-rejected { border-left: 4px solid #ef4444; opacity: 0.7; }
    </style>
</head>
<body class="bg-gray-50">
    <div id="root"></div>

    <script type="text/babel">
        const { useState, useEffect, useCallback, useRef } = React;

        // API 接口
        const api = {
            async getJobs() {
                const response = await fetch('/api/jobs');
                const result = await response.json();
                if (!result.success) throw new Error(result.error || '获取岗位失败');
                return result.data;
            },

            async getCandidates(jobId) {
                const response = await fetch(`/api/jobs/${jobId}/candidates`);
                const result = await response.json();
                if (!result.success) throw new Error(result.error || '获取候选人失败');
                return result.data;
            },

            async getJobDetail(jobId) {
                const response = await fetch(`/api/jobs/${jobId}`);
                const result = await response.json();
                if (!result.success) throw new Error(result.error || '获取岗位详情失败');
                return result.data;
            },

            async analyzeCandidate(jobId, candidateData) {
                const response = await fetch(`/api/jobs/${jobId}/analyze`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(candidateData)
                });
                return await response.json();
            },

            async getAnalysisStatus(candidateId) {
                const response = await fetch(`/api/analysis/${candidateId}/status`);
                return await response.json();
            },

            async sendChatMessage(message, jobId) {
                const response = await fetch('/api/chat', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ message, job_id: jobId })
                });
                const result = await response.json();
                
                // 解析执行信息用于思考过程显示
                if (result.execution_info && result.execution_info.agents_called) {
                    result.thinking_steps = result.execution_info.agents_called.map(step => {
                        const [agent, content] = step.split(':');
                        return {
                            agent: agent.trim(),
                            content: content ? content.trim() : '处理中...'
                        };
                    });
                }
                
                return result;
            },

            // 新增LangGraph相关API
            async processWithLangGraph(userInput, candidates = []) {
                const response = await fetch('/api/process', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ user_input: userInput, candidates })
                });
                return await response.json();
            },

            async getSystemHealth() {
                const response = await fetch('/api/health');
                return await response.json();
            },

            async getChatHistory(limit = 10) {
                const response = await fetch(`/api/chat/history?limit=${limit}`);
                return await response.json();
            },

            async updateCandidateNotes(candidateId, notes, jobId) {
                const response = await fetch(`/api/candidates/${candidateId}/notes`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ notes, job_id: jobId })
                });
                return await response.json();
            },

            async updateCandidateStatus(candidateId, status, jobId) {
                const response = await fetch(`/api/candidates/${candidateId}/status`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ status, job_id: jobId })
                });
                return await response.json();
            }
        };

        // 岗位仪表板组件
        function JobDashboard({ jobs = [], onSelectJob }) {
            return (
                <div className="min-h-screen bg-gray-50">
                    <DashboardHeader />
                    <div className="container mx-auto px-4 py-8">
                        <div className="flex justify-between items-center mb-6">
                            <h2 className="text-2xl font-semibold text-gray-800">招聘任务</h2>
                            <div className="text-sm text-gray-600">
                                共 {jobs.length} 个岗位
                            </div>
                        </div>
                        
                        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                            {jobs.map(job => (
                                <JobCard 
                                    key={job.id} 
                                    job={job} 
                                    onClick={() => onSelectJob(job)} 
                                />
                            ))}
                        </div>
                    </div>
                </div>
            );
        }

        // 仪表板头部
        function DashboardHeader() {
            return (
                <div className="gradient-bg text-white py-8">
                    <div className="container mx-auto px-4">
                        <h1 className="text-3xl font-bold">BoLe HR 智能招聘系统</h1>
                        <p className="text-blue-100 mt-2">基于LangGraph多智能体的智能招聘管理平台</p>
                        <div className="mt-4 flex space-x-6 text-sm">
                            <div>🤖 多Agent协作</div>
                            <div>📊 智能分析</div>
                            <div>🎯 LangGraph工作流</div>
                            <div>💬 自然语言交互</div>
                            <div>🔄 实时协作</div>
                        </div>
                    </div>
                </div>
            );
        }

        // 岗位卡片组件
        function JobCard({ job, onClick }) {
            const getStatusColor = (urgent) => urgent ? 'border-red-400' : 'border-blue-400';
            const getStatusBg = (urgent) => urgent ? 'bg-red-50' : 'bg-blue-50';

            return (
                <div 
                    className={`bg-white rounded-lg shadow-md p-6 card-hover cursor-pointer border-l-4 ${getStatusColor(job.urgent)} ${getStatusBg(job.urgent)}`}
                    onClick={onClick}
                >
                    <div className="flex justify-between items-start mb-4">
                        <div className="flex-1">
                            <h3 className="text-xl font-semibold text-gray-800">{job.title}</h3>
                            <p className="text-gray-600 text-sm">{job.full_title}</p>
                        </div>
                        {job.urgent && (
                            <span className="bg-red-100 text-red-800 text-xs px-2 py-1 rounded-full ml-2">
                                紧急
                            </span>
                        )}
                    </div>
                    
                    <div className="space-y-2 mb-4">
                        <div className="flex justify-between">
                            <span className="text-gray-600 text-sm">公司:</span>
                            <span className="font-medium">{job.company}</span>
                        </div>
                        <div className="flex justify-between">
                            <span className="text-gray-600 text-sm">地点:</span>
                            <span>{job.location}</span>
                        </div>
                        <div className="flex justify-between">
                            <span className="text-gray-600 text-sm">薪资:</span>
                            <span className="text-green-600 font-medium">{job.salary}</span>
                        </div>
                    </div>

                    <div className="mb-4">
                        <p className="text-sm font-medium text-gray-700 mb-2">核心技能:</p>
                        <div className="flex flex-wrap gap-1">
                            {(job.required_skills || []).slice(0, 6).map((skill, index) => (
                                <span key={index} className="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded">
                                    {skill}
                                </span>
                            ))}
                            {(job.required_skills && job.required_skills.length > 6) && (
                                <span className="text-xs text-gray-500 px-2 py-1">
                                    +{job.required_skills.length - 6}
                                </span>
                            )}
                        </div>
                    </div>

                    <div className="flex justify-between items-center pt-4 border-t border-gray-200">
                        <div className="text-sm text-gray-600">
                            <span className="font-medium">申请人数:</span> 
                            <span className="ml-1 text-blue-600 font-semibold">{job.applicants}</span>
                        </div>
                        <div className="text-blue-600 font-medium text-sm">
                            进入招聘空间 →
                        </div>
                    </div>
                </div>
            );
        }

        // 招聘工作空间组件
        function RecruitmentWorkspace({ job, onBack }) {
            const [candidates, setCandidates] = useState([]);
            const [originalCandidates, setOriginalCandidates] = useState([]); // 保存原始候选人列表
            const [selectedCandidate, setSelectedCandidate] = useState(null);
            const [loading, setLoading] = useState(true);
            const [analyzing, setAnalyzing] = useState({});
            const [chatMessages, setChatMessages] = useState([]);
            const [chatInput, setChatInput] = useState("");
            const [chatLoading, setChatLoading] = useState(false);
            const [editingNotes, setEditingNotes] = useState(false);
            const [notesContent, setNotesContent] = useState("");
            const [isFiltered, setIsFiltered] = useState(false); // 标记是否处于筛选状态
            const [viewMode, setViewMode] = useState('chat'); // 'chat' 或 'details'
            const [errorInfo, setErrorInfo] = useState(null); // 错误信息状态
            const chatMessagesRef = useRef(null);
            const radarChartRef = useRef(null);

            // 🚨 全局错误处理
            useEffect(() => {
                const handleError = (event) => {
                    console.error('❌ 全局JavaScript错误:', event.error);
                    setErrorInfo({
                        message: event.error?.message || '未知错误',
                        stack: event.error?.stack || '',
                        timestamp: new Date().toISOString()
                    });
                };
                
                const handleUnhandledRejection = (event) => {
                    console.error('❌ 未处理的Promise拒绝:', event.reason);
                    setErrorInfo({
                        message: event.reason?.message || String(event.reason) || '异步操作失败',
                        stack: event.reason?.stack || '',
                        timestamp: new Date().toISOString()
                    });
                };

                window.addEventListener('error', handleError);
                window.addEventListener('unhandledrejection', handleUnhandledRejection);

                return () => {
                    window.removeEventListener('error', handleError);
                    window.removeEventListener('unhandledrejection', handleUnhandledRejection);
                };
            }, []);

            useEffect(() => {
                loadCandidates();
                loadChatHistory();
            }, [job.id]);

            useEffect(() => {
                // 自动滚动到聊天底部
                if (chatMessagesRef.current) {
                    chatMessagesRef.current.scrollTop = chatMessagesRef.current.scrollHeight;
                }
            }, [chatMessages]);

            // 渲染雷达图 - 增强错误处理
            useEffect(() => {
                if (selectedCandidate && selectedCandidate.ai_analysis && selectedCandidate.ai_analysis.radar_chart_data) {
                    // 延迟渲染确保DOM已更新，并加强错误处理
                    setTimeout(() => {
                        try {
                            renderRadarChart(selectedCandidate);
                        } catch (error) {
                            console.error('雷达图渲染失败:', error);
                            // 不让雷达图错误影响整个界面
                        }
                    }, 150);
                }
            }, [selectedCandidate?.id, selectedCandidate?.ai_analysis?.radar_chart_data]); // 只监听必要的字段变化

            const renderRadarChart = (candidate) => {
                try {
                    if (!candidate?.ai_analysis?.radar_chart_data) {
                        console.log('候选人无雷达图数据，跳过渲染');
                        return;
                    }
                    
                    const canvasId = `radarChart_${candidate.id}`;
                    const canvas = document.getElementById(canvasId);
                    
                    if (!canvas) {
                        console.warn('雷达图画布未找到:', canvasId);
                        return;
                    }

                    // 安全地清除之前的图表
                    if (radarChartRef.current) {
                        try {
                            radarChartRef.current.destroy();
                            radarChartRef.current = null;
                        } catch (e) {
                            console.warn('清除旧图表失败:', e);
                        }
                    }

                    const ctx = canvas.getContext('2d');
                    if (!ctx) {
                        console.error('无法获取Canvas 2D上下文');
                        return;
                    }

                    const chartData = candidate.ai_analysis.radar_chart_data;
                    
                    // 验证图表数据
                    if (!chartData.data || !Array.isArray(chartData.data)) {
                        console.error('雷达图数据格式错误:', chartData);
                        return;
                    }

                    radarChartRef.current = new Chart(ctx, {
                        type: 'radar',
                        data: {
                            labels: chartData.labels || ["技术能力", "工作经验", "可信度", "沟通能力", "教育背景", "领导力", "问题解决"],
                            datasets: [{
                                label: candidate.name || '候选人',
                                data: chartData.data,
                                borderColor: 'rgb(59, 130, 246)',
                                backgroundColor: 'rgba(59, 130, 246, 0.1)',
                                pointBackgroundColor: 'rgb(59, 130, 246)',
                                pointBorderColor: '#fff',
                                pointHoverBackgroundColor: '#fff',
                                pointHoverBorderColor: 'rgb(59, 130, 246)',
                                pointRadius: 4,
                                pointHoverRadius: 6,
                                borderWidth: 2
                            }]
                        },
                        options: {
                            responsive: true,
                            maintainAspectRatio: true,
                            plugins: {
                                legend: {
                                    display: false
                                }
                            },
                            scales: {
                                r: {
                                    angleLines: {
                                        color: 'rgba(0, 0, 0, 0.1)'
                                    },
                                    grid: {
                                        color: 'rgba(0, 0, 0, 0.1)'
                                    },
                                    pointLabels: {
                                        color: '#374151',
                                        font: {
                                            size: 12
                                        }
                                    },
                                    ticks: {
                                        beginAtZero: true,
                                        max: 100,
                                        stepSize: 20,
                                        color: '#6B7280'
                                    }
                                }
                            }
                        }
                    });
                    
                    console.log('✅ 雷达图渲染成功:', candidate.name);
                    
                } catch (error) {
                    console.error('雷达图渲染错误:', error);
                    // 确保错误不会传播到外层
                }
            };

            const loadCandidates = async () => {
                try {
                    console.log('开始加载候选人数据，岗位ID:', job.id);
                    setLoading(true);
                    const candidatesData = await api.getCandidates(job.id);
                    console.log('API返回的候选人数据:', candidatesData);
                    console.log('候选人数量:', candidatesData?.length || 0);
                    setCandidates(candidatesData);
                    setOriginalCandidates(candidatesData); // 保存原始列表
                    setIsFiltered(false); // 重置筛选状态
                    if (candidatesData.length > 0) {
                        setSelectedCandidate(candidatesData[0]);
                        setNotesContent(candidatesData[0].notes || "");
                        console.log('设置选中候选人:', candidatesData[0].name);
                    } else {
                        console.log('没有候选人数据');
                    }
                } catch (err) {
                    console.error('获取候选人失败:', err);
                } finally {
                    setLoading(false);
                }
            };

            // 还原全部候选人
            const showAllCandidates = () => {
                setCandidates(originalCandidates);
                setIsFiltered(false);
                if (originalCandidates.length > 0) {
                    setSelectedCandidate(originalCandidates[0]);
                }
            };

            const loadChatHistory = async () => {
                try {
                    const result = await api.getChatHistory(20);
                    if (result.success) {
                        setChatMessages(result.history);
                    }
                } catch (err) {
                    console.error('获取聊天历史失败:', err);
                }
            };

            const handleSendMessage = async () => {
                if (!chatInput.trim() || chatLoading) return;

                const originalInput = chatInput; // 保存原始输入
                
                const userMessage = {
                    role: "user",
                    content: originalInput,
                    timestamp: new Date().toISOString()
                };

                // 立即更新UI状态
                setChatMessages(prev => [...prev, userMessage]);
                setChatInput("");
                setChatLoading(true);

                try {
                    console.log('发送消息:', originalInput); // 调试日志
                    const result = await api.sendChatMessage(originalInput, job.id);
                    console.log('API响应:', result); // 调试日志
                    
                    if (result && result.success) {
                        console.log('result', result);
                        const assistantMessage = {
                            role: "assistant",
                            content: result.message || result.response || '收到回复但内容为空',
                            timestamp: new Date().toISOString(),
                            action_type: result.action_type || 'unknown',
                            data: result.data || {},
                            timeline: result.timeline || null,  // 添加AI思考时间线
                            execution_info: result.execution_info || null, // 添加LangGraph执行信息
                            system: result.system || 'unknown',  // 系统类型
                            ui_commands: result.ui_commands || [] // UI更新指令
                        };
                        
                        // 如果有时间线，在控制台输出详细信息
                        if (result.timeline && result.timeline.length > 0) {
                            console.log('🕐 AI思考时间线:', result.timeline);
                        }

                        setChatMessages(prev => [...prev, assistantMessage]);

                        // 处理操作结果
                        if (result.data && result.action_type === 'filter') {
                            // 更新候选人列表显示筛选结果
                            const filteredCandidates = result.data.filtered_candidates || [];
                            setCandidates(filteredCandidates);
                            setIsFiltered(true); // 设置筛选状态
                            if (filteredCandidates.length > 0) {
                                setSelectedCandidate(filteredCandidates[0]);
                            } else {
                                setSelectedCandidate(null);
                            }
                        } else if (result.data && result.action_type === 'sort') {
                            // 更新候选人排序
                            const sortedCandidates = result.data.sorted_candidates || candidates;
                            setCandidates(sortedCandidates);
                        } else if (result.action_type === 'update_notes') {
                            // 笔记更新：直接更新本地状态而不是重新加载
                            if (result.data && result.data.updated_candidate_ids) {
                                setCandidates(prev => prev.map(c => {
                                    if (result.data.updated_candidate_ids.includes(c.id)) {
                                        return { ...c, notes: result.data.notes_content };
                                    }
                                    return c;
                                }));
                                
                                // 如果当前选中的候选人被更新了，也要更新详情页
                                if (selectedCandidate && result.data.updated_candidate_ids.includes(selectedCandidate.id)) {
                                    setSelectedCandidate(prev => ({ 
                                        ...prev, 
                                        notes: result.data.notes_content 
                                    }));
                                    setNotesContent(result.data.notes_content);
                                }
                            }
                        } else if (result.action_type === 'generate_analysis') {
                            // 处理AI分析报告
                            console.log('🤖 收到分析报告:', result.data);
                            if (result.data && result.data.analysis_reports) {
                                const reports = result.data.analysis_reports;
                                
                                // 更新候选人的分析结果
                                setCandidates(prev => prev.map(candidate => {
                                    const report = reports.find(r => r.candidate_id === candidate.id);
                                    if (report) {
                                        return {
                                            ...candidate,
                                            ai_analysis: {
                                                overall_score: 85,
                                                technical_score: 90,
                                                credibility_score: 80,
                                                experience_score: 85,
                                                recommendation: "推荐",
                                                reasoning: ["技能匹配度高", "经验丰富", "学习能力强"],
                                                potential_risks: ["需要面试确认", "薪资期望较高"],
                                                detailed_content: report.analysis_content,
                                                radar_chart_data: report.radar_data || {
                                                    labels: ["技术能力", "工作经验", "可信度", "沟通能力", "教育背景", "领导力", "问题解决"],
                                                    data: [90, 85, 80, 75, 85, 70, 88]
                                                },
                                                generated_at: report.generated_at
                                            }
                                        };
                                    }
                                    return candidate;
                                }));
                                
                                // 如果当前选中的候选人有分析报告，更新选中状态
                                if (selectedCandidate) {
                                    const candidateReport = reports.find(r => r.candidate_id === selectedCandidate.id);
                                    if (candidateReport) {
                                        setSelectedCandidate(prev => ({
                                            ...prev,
                                            ai_analysis: {
                                                overall_score: 85,
                                                technical_score: 90,
                                                credibility_score: 80,
                                                experience_score: 85,
                                                recommendation: "推荐",
                                                reasoning: ["技能匹配度高", "经验丰富", "学习能力强"],
                                                potential_risks: ["需要面试确认", "薪资期望较高"],
                                                detailed_content: candidateReport.analysis_content,
                                                radar_chart_data: candidateReport.radar_data || {
                                                    labels: ["技术能力", "工作经验", "可信度", "沟通能力", "教育背景", "领导力", "问题解决"],
                                                    data: [90, 85, 80, 75, 85, 70, 88]
                                                },
                                                generated_at: candidateReport.generated_at
                                            }
                                        }));
                                    }
                                }
                            }
                        } else if (result.action_type === 'archive') {
                            // 状态更改时重新加载数据
                            await loadCandidates();
                        }
                    } else {
                        throw new Error(result?.error || 'API返回格式错误');
                    }
                } catch (err) {
                    console.error('聊天消息发送失败:', err); // 调试日志
                    const errorMessage = {
                        role: "assistant",
                        content: `抱歉，处理您的请求时出现错误：${err.message || '未知错误'}`,
                        timestamp: new Date().toISOString(),
                        action_type: "error"
                    };
                    setChatMessages(prev => [...prev, errorMessage]);
                } finally {
                    setChatLoading(false);
                }
            };

            const handleKeyPress = (e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    handleSendMessage();
                }
            };

            const handleAnalyze = async (candidate) => {
                try {
                    setAnalyzing(prev => ({ ...prev, [candidate.id]: true }));
                    
                    const result = await api.analyzeCandidate(job.id, {
                        candidate_id: candidate.id
                    });

                    if (result.success) {
                        pollAnalysisStatus(candidate.id);
                    }
                } catch (err) {
                    console.error('启动分析失败:', err);
                    setAnalyzing(prev => ({ ...prev, [candidate.id]: false }));
                }
            };

            const pollAnalysisStatus = async (candidateId) => {
                const poll = async () => {
                    try {
                        const status = await api.getAnalysisStatus(candidateId);
                        
                        if (status.success) {
                            if (status.status === 'completed') {
                                setCandidates(prev => prev.map(c => 
                                    c.id === candidateId 
                                        ? { ...c, ai_analysis: status.result, score: status.result.overall_score }
                                        : c
                                ));
                                setAnalyzing(prev => ({ ...prev, [candidateId]: false }));
                                
                                // 如果是当前选中的候选人，更新选中状态
                                if (selectedCandidate && selectedCandidate.id === candidateId) {
                                    setSelectedCandidate(prev => ({
                                        ...prev,
                                        ai_analysis: status.result,
                                        score: status.result.overall_score
                                    }));
                                }
                                return;
                            } else if (status.status === 'in_progress') {
                                setTimeout(poll, 3000);
                            } else {
                                setAnalyzing(prev => ({ ...prev, [candidateId]: false }));
                            }
                        }
                    } catch (err) {
                        console.error('获取分析状态失败:', err);
                        setAnalyzing(prev => ({ ...prev, [candidateId]: false }));
                    }
                };
                
                poll();
            };

            const handleSaveNotes = async () => {
                if (!selectedCandidate) {
                    console.log('❌ 保存笔记失败: 没有选择候选人');
                    return;
                }
                
                console.log('📝 开始保存笔记:', {
                    candidateId: selectedCandidate.id,
                    candidateName: selectedCandidate.name,
                    notesLength: notesContent.length,
                    jobId: job.id
                });
                
                try {
                    // 显示保存中状态
                    const result = await api.updateCandidateNotes(
                        selectedCandidate.id, 
                        notesContent, 
                        job.id
                    );
                    
                    console.log('📝 笔记保存API响应:', result);
                    
                    if (result.success) {
                        // 🔒 安全地更新候选人状态 - 确保不丢失任何重要字段
                        setSelectedCandidate(prev => {
                            if (!prev) {
                                console.error('❌ selectedCandidate为空，无法更新笔记');
                                return prev;
                            }
                            const updated = { 
                                ...prev, 
                                notes: notesContent,
                                updated_at: new Date().toISOString()
                            };
                            console.log('📝 更新选中候选人笔记:', {
                                id: updated.id,
                                name: updated.name,
                                notesLength: notesContent.length
                            });
                            return updated;
                        });
                        
                        setCandidates(prev => prev.map(c => {
                            if (c.id === selectedCandidate.id) {
                                return { 
                                    ...c, 
                                    notes: notesContent,
                                    updated_at: new Date().toISOString()
                                };
                            }
                            return c;
                        }));
                        
                        setEditingNotes(false);
                        console.log('✅ 笔记保存成功 - 状态已更新');
                    } else {
                        console.error('❌ 笔记保存失败:', result.message || 'Unknown error');
                        alert(`笔记保存失败: ${result.message || '未知错误'}`);
                    }
                } catch (err) {
                    console.error('❌ 保存笔记网络错误:', err);
                    alert(`保存笔记时出现网络错误: ${err.message || err}`);
                    
                    // 网络错误时不要改变UI状态，让用户可以重试
                }
            };

            const handleStatusChange = async (candidateId, newStatus) => {
                try {
                    const result = await api.updateCandidateStatus(candidateId, newStatus, job.id);
                    
                    if (result.success) {
                        setCandidates(prev => prev.map(c => 
                            c.id === candidateId ? { ...c, status: newStatus } : c
                        ));
                        
                        if (selectedCandidate && selectedCandidate.id === candidateId) {
                            setSelectedCandidate(prev => ({ ...prev, status: newStatus }));
                        }
                    }
                } catch (err) {
                    console.error('更新状态失败:', err);
                }
            };

            // 🚨 错误显示
            if (errorInfo) {
                return (
                    <div className="min-h-screen bg-gray-50 flex items-center justify-center">
                        <div className="max-w-lg mx-auto bg-white rounded-lg shadow-lg p-6">
                            <div className="flex items-center mb-4">
                                <div className="text-red-500 text-2xl mr-3">⚠️</div>
                                <h3 className="text-lg font-semibold text-gray-800">系统错误</h3>
                            </div>
                            <div className="mb-4">
                                <p className="text-gray-600 mb-2">抱歉，系统遇到了一个错误：</p>
                                <p className="text-red-600 font-mono text-sm bg-red-50 p-2 rounded">
                                    {errorInfo.message}
                                </p>
                            </div>
                            <div className="flex space-x-3">
                                <button
                                    onClick={() => {
                                        setErrorInfo(null);
                                        window.location.reload();
                                    }}
                                    className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
                                >
                                    重新加载页面
                                </button>
                                <button
                                    onClick={() => setErrorInfo(null)}
                                    className="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
                                >
                                    继续使用
                                </button>
                                <button
                                    onClick={onBack}
                                    className="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400"
                                >
                                    返回主页
                                </button>
                            </div>
                            <details className="mt-4">
                                <summary className="cursor-pointer text-sm text-gray-500">查看详细错误信息</summary>
                                <pre className="mt-2 text-xs text-gray-600 bg-gray-50 p-2 rounded overflow-auto max-h-32">
                                    {errorInfo.stack || '无详细信息'}
                                </pre>
                            </details>
                        </div>
                    </div>
                );
            }

            if (loading) {
                return <WorkspaceLoader onBack={onBack} job={job} />;
            }

            return (
                <div className="min-h-screen bg-gray-50">
                    <WorkspaceHeader job={job} onBack={onBack} />
                    
                    {/* 标签页导航 */}
                    <div className="bg-white border-b border-gray-200">
                        <div className="container mx-auto px-6">
                            <nav className="flex space-x-8">
                                <button
                                    className={`py-4 px-2 border-b-2 font-medium text-sm ${
                                        viewMode === 'chat' 
                                            ? 'border-blue-500 text-blue-600' 
                                            : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
                                    }`}
                                    onClick={() => setViewMode('chat')}
                                >
                                    💬 AI 对话助手
                                </button>
                                <button
                                    className={`py-4 px-2 border-b-2 font-medium text-sm ${
                                        viewMode === 'details' 
                                            ? 'border-blue-500 text-blue-600' 
                                            : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
                                    }`}
                                    onClick={() => setViewMode('details')}
                                    disabled={!selectedCandidate}
                                >
                                    👤 候选人详情 {selectedCandidate ? `(${selectedCandidate.name})` : ''}
                                </button>
                            </nav>
                        </div>
                    </div>

                    {/* 主内容区域 */}
                    {viewMode === 'chat' ? (
                        /* 全屏AI对话视图 */
                        <div className="h-screen flex flex-col pt-20">
                            {/* 聊天消息区域 */}
                            <div className="flex-1 overflow-hidden flex">
                                {/* 左侧：聊天对话 */}
                                <div className="flex-1 flex flex-col bg-white">
                                    <div className="flex-1 overflow-y-auto p-6" ref={chatMessagesRef}>
                                        {chatMessages.map((message, index) => (
                                            <ChatMessage key={index} message={message} />
                                        ))}
                                        {chatMessages.length === 0 && (
                                            <div className="text-center text-gray-500 py-12">
                                                <div className="text-6xl mb-4">🤖</div>
                                                <h3 className="text-xl font-medium mb-2">AI 招聘助手</h3>
                                                <p className="text-gray-400">开始与AI对话，智能筛选和分析候选人</p>
                                                <div className="mt-6 text-sm text-gray-400">
                                                    <p>你可以尝试说：</p>
                                                    <ul className="mt-2 space-y-1">
                                                        <li>• "筛选出有Python经验的候选人"</li>
                                                        <li>• "按技术能力排序"</li>
                                                        <li>• "给张三添加笔记：面试表现优秀"</li>
                                                    </ul>
                                                </div>
                                            </div>
                                        )}
                                        {chatLoading && (
                                            <div className="message-assistant p-3 rounded-lg mb-2 flex items-center">
                                                <span className="typing-indicator mr-2"></span>
                                                <span className="text-sm">AI正在思考...</span>
                                            </div>
                                        )}
                                    </div>
                                    
                                    {/* 输入区域 */}
                                    <div className="border-t border-gray-200 p-6 bg-gray-50">
                                        <div className="flex space-x-4">
                                            <input
                                                type="text"
                                                value={chatInput}
                                                onChange={(e) => setChatInput(e.target.value)}
                                                onKeyPress={(e) => e.key === 'Enter' && !chatLoading && handleSendMessage()}
                                                placeholder="与AI助手对话：筛选候选人、添加笔记、分析比较..."
                                                className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                                                disabled={chatLoading}
                                            />
                                            <button
                                                onClick={handleSendMessage}
                                                disabled={chatLoading || !chatInput.trim()}
                                                className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed font-medium"
                                            >
                                                {chatLoading ? '处理中...' : '发送'}
                                            </button>
                                        </div>
                                    </div>
                                </div>

                                {/* 右侧：候选人列表（紧凑版） */}
                                <div className="w-80 bg-gray-100 border-l border-gray-200">
                                    <div className="p-4 bg-white border-b border-gray-200">
                                        <div className="flex justify-between items-center">
                                            <h3 className="font-semibold text-gray-800">候选人列表</h3>
                                            <div className="flex items-center space-x-2">
                                                <span className="text-sm text-gray-600">{candidates.length}人</span>
                                                {isFiltered && (
                                                    <button
                                                        onClick={showAllCandidates}
                                                        className="px-2 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700"
                                                    >
                                                        显示全部
                                                    </button>
                                                )}
                                            </div>
                                        </div>
                                    </div>
                                    
                                    <div className="h-full overflow-y-auto p-4 space-y-3">
                                        {candidates.map(candidate => (
                                            <div 
                                                key={candidate.id}
                                                className={`p-3 bg-white rounded-lg border cursor-pointer hover:shadow-md transition-all ${
                                                    selectedCandidate?.id === candidate.id 
                                                        ? 'border-blue-500 shadow-md bg-blue-50' 
                                                        : 'border-gray-200'
                                                }`}
                                                onClick={() => {
                                                    setSelectedCandidate(candidate);
                                                    setNotesContent(candidate.notes || "");
                                                    setEditingNotes(false);
                                                    setViewMode('details');
                                                }}
                                            >
                                                <div className="flex justify-between items-start mb-2">
                                                    <h4 className="font-medium text-sm text-gray-800 truncate">{candidate.name}</h4>
                                                    <StatusDropdown 
                                                        currentStatus={candidate.status || 'active'}
                                                        onChange={(status) => handleStatusChange(candidate.id, status)}
                                                    />
                                                </div>
                                                <div className="text-xs text-gray-600 mb-2">
                                                    <span className="bg-gray-100 px-2 py-1 rounded text-xs">{candidate.category}</span>
                                                </div>
                                                {candidate.score > 0 && (
                                                    <div className="flex items-center space-x-1">
                                                        <span className="text-xs font-medium">{candidate.score.toFixed(0)}分</span>
                                                        <div className="flex-1 bg-gray-200 rounded-full h-1">
                                                            <div 
                                                                className="bg-blue-500 h-1 rounded-full" 
                                                                style={{ width: `${candidate.score}%` }}
                                                            />
                                                        </div>
                                                    </div>
                                                )}
                                            </div>
                                        ))}
                                        
                                        {candidates.length === 0 && (
                                            <div className="text-center py-8">
                                                <div className="text-gray-400 text-3xl mb-2">📄</div>
                                                <p className="text-gray-600 text-sm">暂无候选人</p>
                                            </div>
                                        )}
                                    </div>
                                </div>
                            </div>
                        </div>
                    ) : (
                        /* 候选人详情视图 */
                        <div className="container mx-auto px-6 py-6">
                            <div className="flex space-x-6">
                                <div className="flex-1">
                                    {selectedCandidate ? (
                                        <CandidateDetail
                                            candidate={selectedCandidate}
                                            job={job}
                                            onAnalyze={() => handleAnalyze(selectedCandidate)}
                                            analyzing={analyzing[selectedCandidate.id]}
                                            editingNotes={editingNotes}
                                            notesContent={notesContent}
                                            onEditNotes={() => setEditingNotes(true)}
                                            onNotesChange={(content) => setNotesContent(content)}
                                            onSaveNotes={handleSaveNotes}
                                            onCancelEdit={() => {
                                                setEditingNotes(false);
                                                setNotesContent(selectedCandidate.notes || "");
                                            }}
                                            onStatusChange={(status) => handleStatusChange(selectedCandidate.id, status)}
                                        />
                                    ) : (
                                        <div className="bg-white rounded-lg p-12 text-center">
                                            <div className="text-gray-400 text-6xl mb-4">👤</div>
                                            <h3 className="text-xl font-medium text-gray-600 mb-2">请选择候选人</h3>
                                            <p className="text-gray-500">切换到对话视图选择候选人查看详细信息</p>
                                        </div>
                                    )}
                                </div>
                                
                                <div className="w-80">
                                    <div className="bg-white rounded-lg p-4">
                                        <h3 className="font-semibold text-gray-800 mb-4">候选人列表</h3>
                                        <div className="space-y-2 max-h-96 overflow-y-auto">
                                            {candidates.map(candidate => (
                                                <div 
                                                    key={candidate.id}
                                                    className={`p-2 rounded cursor-pointer text-sm ${
                                                        selectedCandidate?.id === candidate.id 
                                                            ? 'bg-blue-100 text-blue-800' 
                                                            : 'hover:bg-gray-100'
                                                    }`}
                                                    onClick={() => {
                                                        setSelectedCandidate(candidate);
                                                        setNotesContent(candidate.notes || "");
                                                        setEditingNotes(false);
                                                    }}
                                                >
                                                    {candidate.name}
                                                </div>
                                            ))}
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    )}
                </div>
            );
        }

        // AI思考时间线组件
        function AgentTimeline({ timeline }) {
            const [isExpanded, setIsExpanded] = useState(false);
            
            if (!timeline || timeline.length === 0) return null;

            const getStatusIcon = (status) => {
                switch (status) {
                    case 'completed': return '✅';
                    case 'failed': return '❌';
                    case 'processing': return '⏳';
                    default: return '🔄';
                }
            };

            const getStatusColor = (status) => {
                switch (status) {
                    case 'completed': return 'text-green-600';
                    case 'failed': return 'text-red-600';
                    case 'processing': return 'text-yellow-600';
                    default: return 'text-blue-600';
                }
            };

            return (
                <div className="mb-3 border border-gray-200 rounded-lg overflow-hidden bg-gradient-to-r from-blue-50 to-indigo-50">
                    {/* 折叠标题栏 */}
                    <button
                        className="w-full px-4 py-3 bg-gradient-to-r from-blue-100 to-indigo-100 hover:from-blue-150 hover:to-indigo-150 flex items-center justify-between text-left transition-all duration-200"
                        onClick={() => setIsExpanded(!isExpanded)}
                    >
                        <div className="flex items-center space-x-3">
                            <span className="text-xl animate-pulse">🤖</span>
                            <div>
                                <span className="font-semibold text-gray-800">AI思考时间线</span>
                                <div className="text-xs text-gray-600">共{(timeline || []).length}个处理步骤</div>
                            </div>
                        </div>
                        <div className="flex items-center space-x-3">
                            <div className="flex space-x-1">
                                {(timeline || []).slice(-3).map((entry, idx) => (
                                    <span key={idx} className="text-sm">
                                        {getStatusIcon(entry.status)}
                                    </span>
                                ))}
                            </div>
                            <span className={`transform transition-transform duration-200 ${isExpanded ? 'rotate-180' : ''}`}>
                                <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                                    <path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
                                </svg>
                            </span>
                        </div>
                    </button>
                    
                    {/* 展开的时间线内容 */}
                    {isExpanded && (
                        <div className="p-4 bg-white">
                            <div className="space-y-4">
                                {timeline.map((entry, index) => (
                                    <div key={index} className="flex items-start space-x-4 relative">
                                        {/* 时间线连接线 */}
                                        {index < timeline.length - 1 && (
                                            <div className="absolute left-6 top-8 w-0.5 h-6 bg-gray-200"></div>
                                        )}
                                        
                                        <div className="flex-shrink-0 mt-1">
                                            <div className="w-12 h-12 rounded-full bg-white border-2 border-gray-200 flex items-center justify-center shadow-sm">
                                                <span className="text-lg">{getStatusIcon(entry.status)}</span>
                                            </div>
                                        </div>
                                        
                                        <div className="flex-1 min-w-0 bg-white rounded-lg border border-gray-100 p-3 shadow-sm">
                                            <div className="flex items-center justify-between mb-2">
                                                <div className="flex items-center space-x-2">
                                                    <span className="font-medium text-gray-900">{entry.agent_name}</span>
                                                    <span className="w-1 h-1 bg-gray-300 rounded-full"></span>
                                                    <span className="text-sm text-blue-600 font-medium">{entry.action}</span>
                                                </div>
                                                <div className="flex items-center space-x-2">
                                                    {entry.duration_ms > 0 && (
                                                        <span className="text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded">
                                                            {entry.duration_ms}ms
                                                        </span>
                                                    )}
                                                    <span className={`text-xs font-medium px-2 py-1 rounded-full ${
                                                        entry.status === 'completed' ? 'bg-green-100 text-green-800' :
                                                        entry.status === 'failed' ? 'bg-red-100 text-red-800' :
                                                        entry.status === 'processing' ? 'bg-yellow-100 text-yellow-800' :
                                                        'bg-blue-100 text-blue-800'
                                                    }`}>
                                                        {entry.status.toUpperCase()}
                                                    </span>
                                                </div>
                                            </div>
                                            <p className="text-sm text-gray-700 mb-2">{entry.details}</p>
                                            <div className="text-xs text-gray-400">
                                                {new Date(entry.timestamp).toLocaleTimeString('zh-CN', {
                                                    hour12: false,
                                                    hour: '2-digit',
                                                    minute: '2-digit',
                                                    second: '2-digit',
                                                    fractionalSecondDigits: 3
                                                })}
                                            </div>
                                        </div>
                                    </div>
                                ))}
                            </div>
                            
                            {/* 总结信息 */}
                            <div className="mt-4 p-3 bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg border border-blue-200">
                                <div className="flex items-center justify-between text-sm">
                                    <span className="text-gray-700">
                                        <strong>处理总览:</strong> {timeline.filter(t => t.status === 'completed').length} 个步骤已完成
                                    </span>
                                    <span className="text-gray-600">
                                        总耗时: {Math.max(...timeline.map(t => t.duration_ms || 0))}ms
                                    </span>
                                </div>
                            </div>
                        </div>
                    )}
                </div>
            );
        }

        // 聊天消息组件
        function ChatMessage({ message }) {
            const isUser = message.role === 'user';
            const messageClass = isUser ? 'message-user' : 'message-assistant';
            
            // 增强的内容渲染
            const renderContent = () => {
                try {
                    const content = message.content || '';
                    
                    if (typeof marked !== 'undefined' && marked.parse) {
                        // 配置marked选项
                        marked.setOptions({
                            breaks: true,     // 支持换行
                            gfm: true,        // GitHub风格markdown 
                            sanitize: false   // 允许HTML
                        });
                        return marked.parse(content);
                    } else {
                        // 增强的文本格式化（当marked未加载时）
                        return content
                            .replace(/\*\*(.*?)\*\*/g, '<strong class="font-bold">$1</strong>') // **粗体**
                            .replace(/\*(.*?)\*/g, '<em class="italic">$1</em>') // *斜体*
                            .replace(/`(.*?)`/g, '<code class="bg-gray-100 px-1 py-0.5 rounded text-xs font-mono">$1</code>') // `代码`
                            .replace(/### (.*?)(?=\n|$)/g, '<h3 class="text-base font-bold mt-3 mb-2 text-gray-800">$1</h3>') // ### 三级标题
                            .replace(/## (.*?)(?=\n|$)/g, '<h2 class="text-lg font-bold mt-3 mb-2 text-gray-800">$1</h2>') // ## 二级标题
                            .replace(/# (.*?)(?=\n|$)/g, '<h1 class="text-xl font-bold mt-3 mb-2 text-gray-800">$1</h1>') // # 一级标题
                            .replace(/^\* (.*)$/gm, '<li class="ml-4 mb-1">• $1</li>') // * 列表项
                            .replace(/^\d+\. (.*)$/gm, '<li class="ml-4 mb-1 list-decimal">$1</li>') // 1. 有序列表
                            .replace(/^\- (.*)$/gm, '<li class="ml-4 mb-1">- $1</li>') // - 列表项
                            .replace(/\n\n/g, '</p><p class="mb-2">') // 双换行成段落
                            .replace(/\n/g, '<br/>') // 单换行
                            .replace(/^/, '<p class="mb-2">') // 开始段落
                            .replace(/$/, '</p>'); // 结束段落
                    }
                } catch (error) {
                    console.error('Markdown渲染错误:', error);
                    return (message.content || '').replace(/\n/g, '<br/>');
                }
            };
            
            return (
                <div className={`${messageClass} p-3 rounded-lg mb-2`}>
                    {/* 显示AI思考时间线 (仅对AI消息) */}
                    {!isUser && message.timeline && <AgentTimeline timeline={message.timeline} />}
                    
                    <div className="markdown-content" 
                         dangerouslySetInnerHTML={{ __html: renderContent() }} />
                    {message.action_type && (
                        <div className="text-xs mt-2 opacity-70">
                            操作类型: {message.action_type}
                        </div>
                    )}
                </div>
            );
        }

        // 工作空间头部
        function WorkspaceHeader({ job, onBack }) {
            return (
                <div className="bg-white border-b shadow-sm px-6 py-4">
                    <div className="flex items-center justify-between">
                        <div className="flex items-center space-x-4">
                            <button 
                                onClick={onBack}
                                className="text-blue-600 hover:text-blue-800 flex items-center"
                            >
                                ← 返回仪表板
                            </button>
                            <div>
                                <h1 className="text-xl font-semibold text-gray-800">{job.title}</h1>
                                <p className="text-sm text-gray-600">{job.company} · {job.location} · {job.salary}</p>
                            </div>
                        </div>
                        <div className="flex items-center space-x-4 text-sm text-gray-600">
                            <span>最低经验: {job.min_experience}年</span>
                            <span>部门: {job.department}</span>
                        </div>
                    </div>
                </div>
            );
        }

        // 工作空间加载器
        function WorkspaceLoader({ onBack, job }) {
            return (
                <div className="min-h-screen bg-gray-50">
                    <WorkspaceHeader job={job} onBack={onBack} />
                    <div className="flex h-screen">
                        <div className="w-3/5 p-4 overflow-y-auto">
                            <div className="bg-white rounded-lg p-8 animate-pulse">
                                <div className="h-6 bg-gray-200 rounded mb-4"></div>
                                <div className="h-4 bg-gray-200 rounded mb-2"></div>
                                <div className="h-4 bg-gray-200 rounded w-3/4"></div>
                            </div>
                        </div>
                        <div className="w-2/5 p-4 bg-gray-100 overflow-y-auto border-l">
                            <div className="space-y-4">
                                {[1, 2, 3].map(i => (
                                    <div key={i} className="h-24 bg-white rounded-lg animate-pulse"></div>
                                ))}
                            </div>
                        </div>
                    </div>
                </div>
            );
        }

        // 候选人卡片组件
        function CandidateCard({ candidate, selected, onClick, analyzing, onStatusChange }) {
            const getScoreColor = (score) => {
                if (score >= 85) return 'score-excellent';
                if (score >= 70) return 'score-good';
                if (score >= 60) return 'score-average';
                return 'score-poor';
            };

            const getScoreText = (score) => {
                if (score >= 85) return '优秀';
                if (score >= 70) return '良好';
                if (score >= 60) return '一般';
                return '待提升';
            };

            const getStatusClass = (status = 'active') => {
                switch(status) {
                    case 'active': return 'status-active';
                    case 'archived': return 'status-archived';
                    case 'rejected': return 'status-rejected';
                    default: return 'status-active';
                }
            };

            return (
                <div 
                    className={`bg-white rounded-lg p-4 cursor-pointer transition-all border-l-4 ${getStatusClass(candidate.status)} ${
                        selected ? 'border-l-blue-500 border border-blue-200 shadow-lg bg-blue-50' : 'border-l-gray-300 border border-gray-200 hover:shadow-md hover:border-l-blue-400'
                    }`}
                    onClick={onClick}
                >
                    {/* 候选人基本信息头部 */}
                    <div className="flex justify-between items-start mb-3">
                        <div className="flex-1">
                            <div className="flex items-center space-x-2 mb-1">
                                {/* 姓名和编号 */}
                                <h3 className="font-semibold text-gray-800 text-sm">{candidate.name}</h3>
                                <StatusDropdown 
                                    currentStatus={candidate.status || 'active'}
                                    onChange={onStatusChange}
                                />
                            </div>
                            
                            {/* 类别和联系信息 */}
                            <div className="text-xs text-gray-600 space-y-1">
                                <div className="flex items-center space-x-3">
                                    <span className="bg-gray-100 px-2 py-1 rounded text-xs">{candidate.category}</span>
                                    {candidate.email && (
                                        <span>📧 {candidate.email}</span>
                                    )}
                                </div>
                                {candidate.phone && (
                                    <div>📱 {candidate.phone}</div>
                                )}
                            </div>
                        </div>
                    </div>

                    {/* AI分析状态 */}
                    {analyzing ? (
                        <div className="mb-2 text-xs text-blue-600 flex items-center bg-blue-50 px-2 py-1 rounded">
                            <span className="typing-indicator mr-2"></span>
                            AI分析中...
                        </div>
                    ) : candidate.score > 0 ? (
                        <div className="mb-2 flex items-center space-x-2">
                            <div className={`px-2 py-1 rounded text-white text-xs font-medium ${getScoreColor(candidate.score)}`}>
                                {candidate.score.toFixed(0)}分
                            </div>
                            <span className="text-xs text-gray-600">
                                {getScoreText(candidate.score)}
                            </span>
                        </div>
                    ) : (
                        <div className="mb-2 text-xs text-gray-500 bg-gray-50 px-2 py-1 rounded">
                            待分析
                        </div>
                    )}

                    {/* 简历预览 */}
                    <div className="text-xs text-gray-600 bg-gray-50 p-2 rounded mb-2">
                        <div className="line-clamp-2">
                            {candidate.resume_preview?.substring(0, 120)}...
                        </div>
                    </div>

                    {/* 底部信息 */}
                    <div className="flex items-center justify-between text-xs">
                        <div className="flex items-center space-x-2">
                            {candidate.notes && (
                                <span className="text-green-600 bg-green-50 px-2 py-1 rounded">
                                    📝 有笔记
                                </span>
                            )}
                            {selected && (
                                <span className="text-blue-600 bg-blue-100 px-2 py-1 rounded">
                                    已选中
                                </span>
                            )}
                        </div>
                    </div>
                </div>
            );
        }

        // 状态下拉菜单
        function StatusDropdown({ currentStatus, onChange }) {
            const [isOpen, setIsOpen] = useState(false);
            
            const statuses = [
                { value: 'active', label: '激活', color: 'text-green-600' },
                { value: 'archived', label: '归档', color: 'text-gray-600' },
                { value: 'rejected', label: '拒绝', color: 'text-red-600' }
            ];

            const currentStatusObj = statuses.find(s => s.value === currentStatus) || statuses[0];

            return (
                <div className="relative" onClick={(e) => e.stopPropagation()}>
                    <button 
                        onClick={() => setIsOpen(!isOpen)}
                        className={`text-xs px-2 py-1 rounded ${currentStatusObj.color} hover:bg-gray-100`}
                    >
                        {currentStatusObj.label} ▼
                    </button>
                    
                    {isOpen && (
                        <div className="absolute right-0 mt-1 bg-white border rounded-lg shadow-lg z-10 min-w-20">
                            {statuses.map(status => (
                                <button
                                    key={status.value}
                                    onClick={() => {
                                        onChange(status.value);
                                        setIsOpen(false);
                                    }}
                                    className={`block w-full text-left px-3 py-2 text-xs hover:bg-gray-100 ${status.color}`}
                                >
                                    {status.label}
                                </button>
                            ))}
                        </div>
                    )}
                </div>
            );
        }

        // 简历预览组件
        function ResumePreview({ candidate }) {
            const [isExpanded, setIsExpanded] = useState(false);
            const resumeText = candidate.resume_full_text || candidate.resume_preview || '';
            
            const formatResume = (text) => {
                // 简单的格式化处理
                const lines = text.split('\n').filter(line => line.trim());
                const formatted = [];
                
                for (let line of lines) {
                    line = line.trim();
                    if (line.length < 3) continue;
                    
                    // 检测是否是标题行（通常是大写、短行或包含特殊字符）
                    if (line.length < 30 && (
                        line.toUpperCase() === line || 
                        /^[A-Z\s\-:]+$/.test(line) ||
                        line.includes('EXPERIENCE') || 
                        line.includes('EDUCATION') || 
                        line.includes('SKILLS') ||
                        line.includes('SUMMARY') ||
                        line.includes('CONTACT')
                    )) {
                        formatted.push({ type: 'header', text: line });
                    } else {
                        formatted.push({ type: 'content', text: line });
                    }
                }
                
                return formatted;
            };
            
            const formattedLines = formatResume(resumeText) || [];
            const previewLines = isExpanded ? formattedLines : (formattedLines || []).slice(0, 8);
            
            return (
                <div className="mb-6">
                    <div className="flex justify-between items-center mb-3">
                        <h3 className="text-lg font-semibold text-gray-800">简历内容</h3>
                        {formattedLines.length > 8 && (
                            <button
                                onClick={() => setIsExpanded(!isExpanded)}
                                className="text-blue-600 hover:text-blue-800 text-sm font-medium"
                            >
                                {isExpanded ? '收起 ▲' : '展开更多 ▼'}
                            </button>
                        )}
                    </div>
                    
                    <div className={`bg-gray-50 rounded-lg p-4 border ${isExpanded ? 'max-h-96' : 'max-h-48'} overflow-y-auto transition-all duration-300`}>
                        {previewLines.map((line, index) => (
                            <div key={index} className={line.type === 'header' ? 'font-semibold text-gray-900 mt-3 mb-1 text-sm' : 'text-sm text-gray-700 mb-2'}>
                                {line.text}
                            </div>
                        ))}
                        
                        {!isExpanded && formattedLines.length > 8 && (
                            <div className="text-center mt-3">
                                <span className="text-gray-500 text-xs">... 还有 {formattedLines.length - 8} 行内容</span>
                            </div>
                        )}
                    </div>
                </div>
            );
        }

        // 候选人详情组件
        function CandidateDetail({ candidate, job, onAnalyze, analyzing, editingNotes, notesContent, onEditNotes, onNotesChange, onSaveNotes, onCancelEdit, onStatusChange }) {
            return (
                <div className="bg-white rounded-lg p-6 candidate-detail-panel">
                    <div className="flex items-start justify-between mb-6">
                        <div className="flex items-center space-x-4">
                            <img 
                                src={candidate.avatar} 
                                alt={candidate.name}
                                className="w-16 h-16 rounded-full object-cover"
                            />
                            <div>
                                <h2 className="text-2xl font-bold text-gray-800">{candidate.name}</h2>
                                <p className="text-gray-600">{candidate.email}</p>
                                <p className="text-gray-600">{candidate.phone}</p>
                                <div className="flex items-center space-x-2 mt-1">
                                    <span className="text-sm text-gray-500">状态:</span>
                                    <StatusDropdown 
                                        currentStatus={candidate.status || 'active'}
                                        onChange={onStatusChange}
                                    />
                                </div>
                            </div>
                        </div>
                        
                        <button 
                            onClick={onAnalyze}
                            disabled={analyzing || candidate.ai_analysis}
                            className={`px-6 py-2 rounded-lg font-medium ${
                                analyzing 
                                    ? 'bg-blue-100 text-blue-600 cursor-not-allowed'
                                    : candidate.ai_analysis
                                    ? 'bg-green-100 text-green-600'
                                    : 'bg-blue-600 text-white hover:bg-blue-700'
                            }`}
                        >
                            {analyzing ? '🤖 分析中...' : candidate.ai_analysis ? '✅ 已分析' : '🔍 AI分析'}
                        </button>
                    </div>

                    {/* 基本信息 */}
                    <div className="mb-6">
                        <h3 className="text-lg font-semibold text-gray-800 mb-3">基本信息</h3>
                        <div className="grid grid-cols-2 gap-4 text-sm">
                            <div>
                                <span className="font-medium text-gray-700">类别:</span>
                                <span className="ml-2">{candidate.category}</span>
                            </div>
                            <div>
                                <span className="font-medium text-gray-700">相关性:</span>
                                <span className="ml-2">{candidate.relevance_score}/5</span>
                            </div>
                        </div>
                    </div>

                    {/* 简历预览 */}
                    <ResumePreview candidate={candidate} />

                    {/* 笔记区域 */}
                    <div className="mb-6">
                        <div className="flex justify-between items-center mb-3">
                            <h3 className="text-lg font-semibold text-gray-800">HR笔记</h3>
                            {!editingNotes && (
                                <button
                                    onClick={onEditNotes}
                                    className="text-blue-600 hover:text-blue-800 text-sm"
                                >
                                    📝 编辑笔记
                                </button>
                            )}
                        </div>
                        
                        {editingNotes ? (
                            <div className="space-y-3">
                                <textarea
                                    value={notesContent}
                                    onChange={(e) => onNotesChange(e.target.value)}
                                    placeholder="在此添加关于候选人的笔记..."
                                    className="w-full p-3 border rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-blue-500"
                                    rows="4"
                                />
                                <div className="flex space-x-2">
                                    <button
                                        onClick={onSaveNotes}
                                        className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700"
                                    >
                                        保存
                                    </button>
                                    <button
                                        onClick={onCancelEdit}
                                        className="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600"
                                    >
                                        取消
                                    </button>
                                </div>
                            </div>
                        ) : (
                            <div className="bg-yellow-50 rounded-lg p-4 min-h-20">
                                {candidate.notes ? (
                                    <div className="markdown-content text-sm text-gray-700"
                                         dangerouslySetInnerHTML={{ 
                                             __html: (typeof marked !== 'undefined' && marked.parse) 
                                                 ? marked.parse(candidate.notes) 
                                                 : candidate.notes.replace(/\n/g, '<br/>') 
                                         }} />
                                ) : (
                                    <p className="text-gray-500 text-sm italic">暂无笔记，点击编辑添加</p>
                                )}
                            </div>
                        )}
                    </div>

                    {/* AI分析结果 */}
                    {candidate.ai_analysis && (
                        <div className="space-y-6">
                            <div>
                                <h3 className="text-lg font-semibold text-gray-800 mb-3">🤖 AI分析结果</h3>
                                
                                {/* 评分概览 */}
                                <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
                                    <ScoreCard label="综合评分" score={candidate.ai_analysis.overall_score} />
                                    <ScoreCard label="技术能力" score={candidate.ai_analysis.technical_score} />
                                    <ScoreCard label="可信度" score={candidate.ai_analysis.credibility_score} />
                                    <ScoreCard label="经验匹配" score={candidate.ai_analysis.experience_score || 0} />
                                </div>

                                {/* 能力雷达图 */}
                                {candidate.ai_analysis.radar_chart_data && (
                                    <div className="bg-white rounded-lg border p-4 mb-6">
                                        <h4 className="font-medium text-gray-800 mb-3">📊 能力维度分析</h4>
                                        <div className="flex justify-center">
                                            <canvas id={`radarChart_${candidate.id}`} width="400" height="400"></canvas>
                                        </div>
                                    </div>
                                )}

                                {/* 推荐结果 */}
                                <div className="bg-blue-50 rounded-lg p-4 mb-4">
                                    <h4 className="font-medium text-blue-900 mb-2">推荐结果</h4>
                                    <p className="text-blue-800">{candidate.ai_analysis.recommendation}</p>
                                </div>

                                {/* 详细分析 */}
                                {candidate.ai_analysis.reasoning && candidate.ai_analysis.reasoning.length > 0 && (
                                    <div className="mb-4">
                                        <h4 className="font-medium text-gray-800 mb-2">分析理由</h4>
                                        <ul className="space-y-1">
                                            {candidate.ai_analysis.reasoning.map((reason, index) => (
                                                <li key={index} className="flex items-start space-x-2">
                                                    <span className="text-green-500 mt-1">✓</span>
                                                    <span className="text-gray-700 text-sm">{reason}</span>
                                                </li>
                                            ))}
                                        </ul>
                                    </div>
                                )}

                                {/* 面试问题 */}
                                {candidate.ai_analysis.interview_questions && candidate.ai_analysis.interview_questions.length > 0 && (
                                    <div className="mb-4">
                                        <h4 className="font-medium text-gray-800 mb-2">建议面试问题</h4>
                                        <div className="space-y-3">
                                            {candidate.ai_analysis.interview_questions.map((q, index) => (
                                                <div key={index} className="bg-gray-50 rounded-lg p-3">
                                                    <div className="text-sm font-medium text-gray-800">{q.category}</div>
                                                    <div className="text-sm text-gray-700 mt-1">{q.question}</div>
                                                    {q.reasoning && (
                                                        <div className="text-xs text-gray-600 mt-1">理由: {q.reasoning}</div>
                                                    )}
                                                </div>
                                            ))}
                                        </div>
                                    </div>
                                )}

                                {/* 薪资建议 */}
                                {candidate.ai_analysis.salary_recommendation && (
                                    <div className="bg-green-50 rounded-lg p-4 mb-4">
                                        <h4 className="font-medium text-green-900 mb-2">薪资建议</h4>
                                        <p className="text-green-800">{candidate.ai_analysis.salary_recommendation}</p>
                                    </div>
                                )}

                                {/* 详细分析内容 */}
                                {candidate.ai_analysis.detailed_content && (
                                    <div className="bg-gradient-to-br from-gray-50 to-blue-50 rounded-lg p-6 border border-gray-200">
                                        <h4 className="font-semibold text-gray-900 mb-4 flex items-center">
                                            📋 完整分析报告
                                            {candidate.ai_analysis.generated_at && (
                                                <span className="ml-2 text-xs text-gray-500 font-normal">
                                                    {new Date(candidate.ai_analysis.generated_at).toLocaleString()}
                                                </span>
                                            )}
                                        </h4>
                                        <div className="prose prose-sm max-w-none text-gray-700 bg-white rounded-lg p-4 shadow-sm"
                                             dangerouslySetInnerHTML={{ 
                                                 __html: (typeof marked !== 'undefined' && marked.parse) 
                                                     ? marked.parse(candidate.ai_analysis.detailed_content) 
                                                     : candidate.ai_analysis.detailed_content.replace(/\n/g, '<br/>') 
                                             }} />
                                    </div>
                                )}
                            </div>
                        </div>
                    )}
                </div>
            );
        }

        // 评分卡片组件
        function ScoreCard({ label, score }) {
            const getScoreColor = (score) => {
                if (score >= 85) return 'bg-green-500';
                if (score >= 70) return 'bg-blue-500';
                if (score >= 60) return 'bg-yellow-500';
                return 'bg-red-500';
            };

            return (
                <div className="bg-white rounded-lg p-4 text-center shadow-sm border">
                    <div className={`w-12 h-12 rounded-full ${getScoreColor(score)} text-white flex items-center justify-center mx-auto mb-2`}>
                        <span className="text-sm font-bold">{Math.round(score)}</span>
                    </div>
                    <div className="text-xs text-gray-600">{label}</div>
                </div>
            );
        }

        // 简单路由功能
        function useRouter() {
            const [currentPath, setCurrentPath] = useState(window.location.hash || '#dashboard');
            
            useEffect(() => {
                const handleHashChange = () => {
                    setCurrentPath(window.location.hash || '#dashboard');
                };
                
                window.addEventListener('hashchange', handleHashChange);
                return () => window.removeEventListener('hashchange', handleHashChange);
            }, []);
            
            const navigate = (path) => {
                window.location.hash = path;
                setCurrentPath(path);
            };
            
            return { currentPath, navigate };
        }

        // 主应用组件
        function App() {
            const { currentPath, navigate } = useRouter();
            const [jobs, setJobs] = useState([]);
            const [loading, setLoading] = useState(true);
            const [error, setError] = useState(null);

            useEffect(() => {
                loadJobs();
            }, []);
            
            const loadJobs = async () => {
                try {
                    setLoading(true);
                    setError(null);
                    console.log('🚀 开始加载岗位数据...');
                    const jobsData = await api.getJobs();
                    console.log('✅ 岗位数据加载成功:', jobsData?.length || 0, '个岗位');
                    setJobs(jobsData || []);
                } catch (err) {
                    console.error('❌ 获取岗位失败:', err);
                    setError(`获取岗位数据失败: ${err.message || err}`);
                } finally {
                    setLoading(false);
                }
            };

            const handleSelectJob = (job) => {
                navigate(`#job/${job.id}`);
            };

            const handleBackToDashboard = () => {
                navigate('#dashboard');
            };
            
            // 路由解析
            const getRouteInfo = () => {
                if (currentPath === '#dashboard' || currentPath === '' || currentPath === '#') {
                    return { view: 'dashboard', jobId: null };
                } else if (currentPath.startsWith('#job/')) {
                    const jobId = currentPath.split('/')[1]; // 保持字符串类型
                    return { view: 'workspace', jobId };
                } else {
                    return { view: 'dashboard', jobId: null };
                }
            };
            
            const { view, jobId } = getRouteInfo();
            console.log('🔍 路由解析结果:', { view, jobId, jobIdType: typeof jobId });
            console.log('📋 可用岗位:', jobs.map(j => ({ id: j.id, idType: typeof j.id, title: j.title })));
            const selectedJob = jobId ? jobs.find(job => {
                const match = job.id === jobId;
                console.log(`🔍 岗位匹配检查: ${job.id}(${typeof job.id}) === ${jobId}(${typeof jobId}) = ${match}`);
                return match;
            }) : null;
            console.log('🎯 选中的岗位:', selectedJob ? selectedJob.title : '未找到岗位');

            // 全局错误处理
            useEffect(() => {
                const handleGlobalError = (event) => {
                    console.error('🚨 全局JavaScript错误:', event.error);
                    setError(`应用错误: ${event.error?.message || '未知错误'}`);
                    event.preventDefault();
                };
                
                const handleUnhandledRejection = (event) => {
                    console.error('🚨 未处理的Promise拒绝:', event.reason);
                    setError(`异步操作失败: ${event.reason?.message || String(event.reason) || '未知错误'}`);
                    event.preventDefault();
                };

                window.addEventListener('error', handleGlobalError);
                window.addEventListener('unhandledrejection', handleUnhandledRejection);

                return () => {
                    window.removeEventListener('error', handleGlobalError);
                    window.removeEventListener('unhandledrejection', handleUnhandledRejection);
                };
            }, []);
            
            // 错误状态显示
            if (error) {
                return (
                    <div className="min-h-screen bg-gradient-to-br from-red-50 to-pink-100 flex items-center justify-center">
                        <div className="bg-white rounded-lg shadow-lg p-8 max-w-md mx-4">
                            <div className="text-center mb-6">
                                <div className="text-6xl mb-4">⚠️</div>
                                <h2 className="text-2xl font-bold text-gray-800 mb-2">系统出现问题</h2>
                                <p className="text-gray-600 text-sm mb-4">请稍后重试或联系系统管理员</p>
                            </div>
                            
                            <div className="bg-red-50 rounded-lg p-4 mb-6">
                                <div className="text-red-800 text-sm font-medium">错误详情:</div>
                                <div className="text-red-700 text-sm mt-1 break-words">{error}</div>
                            </div>
                            
                            <div className="flex space-x-3">
                                <button
                                    onClick={() => {
                                        setError(null);
                                        loadJobs();
                                    }}
                                    className="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium"
                                >
                                    重新加载
                                </button>
                                <button
                                    onClick={() => {
                                        setError(null);
                                        setJobs([]);
                                    }}
                                    className="flex-1 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 font-medium"
                                >
                                    继续使用
                                </button>
                            </div>
                            
                            <div className="mt-4 text-xs text-gray-500 text-center">
                                如果问题持续存在，请检查网络连接或刷新页面
                            </div>
                        </div>
                    </div>
                );
            }

            if (loading) {
                return (
                    <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center">
                        <div className="text-center">
                            <div className="text-4xl mb-4 animate-spin">🔄</div>
                            <div className="text-gray-600">正在加载BoLe HR系统...</div>
                            <div className="text-sm text-gray-500 mt-2">请稍候片刻</div>
                        </div>
                    </div>
                );
            }

            return (
                <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
                    {view === 'dashboard' && (
                        <JobDashboard jobs={jobs} onSelectJob={handleSelectJob} />
                    )}
                    {view === 'workspace' && selectedJob && (
                        <RecruitmentWorkspace job={selectedJob} onBack={handleBackToDashboard} />
                    )}
                    {view === 'workspace' && !selectedJob && (
                        <div className="min-h-screen flex items-center justify-center">
                            <div className="text-center">
                                <div className="text-6xl mb-4">🔍</div>
                                <div className="text-gray-600 text-xl">岗位未找到</div>
                                <button
                                    onClick={handleBackToDashboard}
                                    className="mt-4 px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
                                >
                                    返回仪表盘
                                </button>
                            </div>
                        </div>
                    )}
                </div>
            );
        }

        // React错误边界组件
        class ErrorBoundary extends React.Component {
            constructor(props) {
                super(props);
                this.state = { hasError: false, error: null };
            }

            static getDerivedStateFromError(error) {
                return { hasError: true, error: error };
            }

            componentDidCatch(error, errorInfo) {
                console.error('🚨 React错误边界捕获的错误:', error, errorInfo);
            }

            render() {
                if (this.state.hasError) {
                    return React.createElement('div', {
                        className: "min-h-screen bg-gradient-to-br from-red-50 to-pink-100 flex items-center justify-center"
                    }, React.createElement('div', {
                        className: "bg-white rounded-lg shadow-lg p-8 max-w-md mx-4 text-center"
                    }, [
                        React.createElement('div', { key: 'icon', className: "text-6xl mb-4" }, '💥'),
                        React.createElement('h2', { key: 'title', className: "text-2xl font-bold text-gray-800 mb-2" }, '应用崩溃了'),
                        React.createElement('p', { key: 'desc', className: "text-gray-600 text-sm mb-4" }, '很抱歉，应用遇到了无法处理的错误'),
                        React.createElement('div', { key: 'error', className: "bg-red-50 rounded-lg p-4 mb-6" }, [
                            React.createElement('div', { key: 'label', className: "text-red-800 text-sm font-medium" }, '错误信息:'),
                            React.createElement('div', { key: 'msg', className: "text-red-700 text-sm mt-1" }, this.state.error?.message || '未知错误')
                        ]),
                        React.createElement('button', {
                            key: 'reload',
                            className: "px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium",
                            onClick: () => window.location.reload()
                        }, '刷新页面')
                    ]));
                }

                return this.props.children;
            }
        }

        // 应用启动
        (function() {
            console.log('🚀 BoLe HR系统启动中...');
            
            // 检查必要的依赖
            const dependencies = {
                'React': typeof React !== 'undefined',
                'ReactDOM': typeof ReactDOM !== 'undefined',
                'Chart.js': typeof Chart !== 'undefined',
                'marked.js': typeof marked !== 'undefined'
            };
            
            console.log('📦 依赖检查结果:', dependencies);
            
            const missingDeps = Object.entries(dependencies)
                .filter(([name, loaded]) => !loaded)
                .map(([name]) => name);
            
            if (missingDeps.length > 0) {
                console.warn('⚠️ 缺少依赖:', missingDeps.join(', '));
            } else {
                console.log('✅ 所有依赖加载完成');
            }

            try {
                // 使用错误边界包装应用
                ReactDOM.render(
                    React.createElement(ErrorBoundary, {}, 
                        React.createElement(App, {})
                    ), 
                    document.getElementById('root')
                );
                console.log('✅ BoLe HR系统启动成功');
            } catch (error) {
                console.error('❌ 应用启动失败:', error);
                
                // 如果React渲染失败，显示基本错误页面
                const root = document.getElementById('root');
                root.innerHTML = `
                    <div style="min-height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #fef2f2 0%, #fce7f3 100%);">
                        <div style="background: white; border-radius: 8px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); padding: 32px; max-width: 400px; text-align: center;">
                            <div style="font-size: 64px; margin-bottom: 16px;">🚨</div>
                            <h2 style="font-size: 24px; font-weight: bold; color: #374151; margin-bottom: 8px;">系统启动失败</h2>
                            <p style="color: #6b7280; font-size: 14px; margin-bottom: 16px;">应用无法正常启动，可能是浏览器兼容性问题</p>
                            <div style="background: #fef2f2; border-radius: 8px; padding: 16px; margin-bottom: 24px;">
                                <div style="color: #dc2626; font-size: 12px; font-weight: 500;">错误详情:</div>
                                <div style="color: #dc2626; font-size: 12px; margin-top: 4px;">${error.message || error}</div>
                            </div>
                            <button onclick="window.location.reload()" style="background: #3b82f6; color: white; padding: 8px 24px; border: none; border-radius: 8px; cursor: pointer; font-weight: 500;">
                                刷新页面
                            </button>
                            <div style="margin-top: 16px; font-size: 12px; color: #9ca3af;">
                                建议使用Chrome、Firefox或Edge浏览器
                            </div>
                        </div>
                    </div>
                `;
            }
        })();
    </script>
</body>
</html>